package ru.spb.osll.myfit.server.parser;

import java.io.File;
import java.io.PrintStream;
import java.util.Set;
import java.util.Vector;
import java.util.regex.Matcher;

import org.apache.log4j.Logger;

import ru.spb.osll.myfit.common.Include;
import ru.spb.osll.myfit.common.Page;
import ru.spb.osll.myfit.common.PageElement;
import ru.spb.osll.myfit.common.Table;
import ru.spb.osll.myfit.common.TableCell;
import ru.spb.osll.myfit.common.TableStyle;
import ru.spb.osll.myfit.common.TextParsingTools;
import ru.spb.osll.myfit.common.WikiText;
import ru.spb.osll.myfit.fixtures.base.MyFitTableFixture;
import ru.spb.osll.myfit.fixtures.base.OneLineFixture;
import ru.spb.osll.myfit.util.ReflectionUtils;
import ru.spb.osll.myfit.util.StringUtils;
import ru.spb.osll.myfit.wikiverifier.result.TableVerificationResult;
import fit.ColumnFixture;
import fit.RowFixture;
import fitlibrary.DoFixture;
import fitlibrary.SetUpFixture;

public class PageParserUtils {
  private static Logger LOG = Logger.getLogger(PageParserUtils.class);

  public static String tableToString(Table table) {
    String res = "";

    for (Vector<TableCell> line : table.getData()) {
      res = res + "|" + StringUtils.join(line, "|") + "|" +
          TableCreater.LINE_SEPARATOR;
    }
    return res;
  }

  public static String includeToString(Include include) {
    String res = TextParsingTools.INCLUDE;
    res = res + include.getPath() + TableCreater.LINE_SEPARATOR;
    return res;
  }

  public static void printSuggestion(TableVerificationResult tableResult,
                                     PrintStream stream) {
    stream.println("Error in test table:");
    stream.println(PageParserUtils.tableToString(tableResult.getTable()));
    stream.println("Suggestion:");
    stream.println(PageParserUtils.tableToString(tableResult.getSuggestion()));

  }

  public static String pageToString(Page page) {
    String res = "";
    LOG.debug("TableUtils: page elements = " + page.getElements().size());

    for (PageElement pageElement : page.getElements()) {
      if (pageElement instanceof Include) {
        LOG.debug("TableUtils: Include");
        res = res + includeToString((Include) pageElement);
        res = res + TableCreater.LINE_SEPARATOR;
      }

      if (pageElement instanceof Table) {
        LOG.debug("TableUtils: Table");
        res = res + tableToString((Table) pageElement);
        res = res + TableCreater.LINE_SEPARATOR;
      }

      if (pageElement instanceof WikiText) {
        LOG.debug("TableUtils: WikiText");
        res = res + ((WikiText) pageElement).getWikiText();
        res = res + TableCreater.TABLE_SEPARATOR;
      }

    }

    return res;
  }

  public static TableStyle getTableStyle(Class< ? > clazz) {
    LOG.debug("TableUtils: Class Style " + clazz);
    if (clazz == null) {
      return TableStyle.UNKNOWN_FIXTURE;
    }

    Set<String> hierarhy = ReflectionUtils.getClassHierarhy(clazz);

    if (hierarhy.contains(SetUpFixture.class.getCanonicalName())) {
      return TableStyle.SETUP_FIXTURE;
    } else if (hierarhy.contains(DoFixture.class.getCanonicalName())) {
      return TableStyle.DO_FIXTURE;
    } else if (hierarhy.contains(OneLineFixture.class.getCanonicalName())) {
      return TableStyle.ONE_LINE_FIXTIRE;
    } else if (hierarhy.contains(RowFixture.class.getCanonicalName())) {
      return TableStyle.ROW_FIXTURE;
    } else if (hierarhy.contains(MyFitTableFixture.class.getCanonicalName())) {
      return TableStyle.MYFIT_TABLE_FIXTURE;
    } else if (hierarhy.contains(ColumnFixture.class.getCanonicalName())) {
      return TableStyle.COLUMN_FIXTURE;
    } else {
      return TableStyle.UNKNOWN_FIXTURE;
    }
  }

  public static String getFullPath(String root, String path) {
    String fullPath = root;
    if (path != null && !path.isEmpty()) {
      path = path.replaceAll(TextParsingTools.ADDRESS_BAR_SEPARATOR,
          Matcher.quoteReplacement(File.separator));
      fullPath += File.separator + path;
    }

    return fullPath + File.separator + TextParsingTools.DATA_FILE_NAME;
  }
}
